package com.calvin.study.config;

import java.io.IOException;
import java.net.UnknownHostException;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;

@Configuration
public class RedissonConfig {
	
	@Value("${spring.redis.host}")
	private String redisHost;
	
	@Bean(name="redisTemplate")
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<String, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		// Json序列化配置
		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
		// 该方法是指定序列化输入的类型，就是将数据库里的数据按照一定类型存储到redis缓存中。
		// om.enableDefaultTyping(DefaultTyping.NON_FINAL);
		om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,As.WRAPPER_ARRAY);
		jackson2JsonRedisSerializer.setObjectMapper(om);

		StringRedisSerializer strRedsSerializer = new StringRedisSerializer();
		// key采用String的序列化方式
		template.setKeySerializer(strRedsSerializer);
		// hash的key也采用String的序列化方式
		template.setHashKeySerializer(strRedsSerializer);
		
		// value序列化方式采用jackson
		template.setValueSerializer(jackson2JsonRedisSerializer);
		template.setHashValueSerializer(jackson2JsonRedisSerializer);
		template.afterPropertiesSet();
		return template;
	}
	
	@Bean
	public RedissonClient redisson() throws IOException{
		Config config  = new Config();
		config.useSingleServer().setAddress("redis://"+redisHost+":6379").setDatabase(1);
		return Redisson.create(config);
	}

}
